funcmain() { a := [3]int{5, 78, 8} var b [5]int b = a // not possible since [3]int and [5]int are distinct types // 也就是说,如果var b [3]int,那就可以赋值了 }
在上述程序的第 6 行中, 我们试图将类型 [3]int 的变量赋给类型为 [5]int 的变量,这是不允许的,因此编译器将抛出错误 main.go:6: cannot use a (type [3]int) as type [5]int in assignment。
数组是值类型
Go 中的数组是值类型而不是引用类型。这意味着当数组赋值给一个新的变量时,该变量会得到一个原始数组的一个副本。如果对新变量进行更改,则不会影响原始数组。
1 2 3 4 5 6 7 8 9 10 11
package main
import"fmt"
funcmain() { a := [...]string{"USA", "China", "India", "Germany", "France"} b := a // a copy of a is assigned to b b[0] = "Singapore" fmt.Println("a is ", a) fmt.Println("b is ", b) }
a is [USA China India Germany France] b is [Singapore China India Germany France]
同样,当数组作为参数传递给函数时,它们是按值传递,而原始数组保持不变。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
package main
import"fmt"
funcchangeLocal(num [5]int) { num[0] = 55 fmt.Println("inside function ", num) } funcmain() { num := [...]int{5, 6, 7, 8, 8} fmt.Println("before passing to function ", num) changeLocal(num) //num is passed by value fmt.Println("after passing to function ", num) }
//但是这样子,就可以修改原值了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
package main
import"fmt"
funcchangeLocal(num *[5]int) { num[0] = 55 fmt.Println("inside function ", num) } funcmain() { num := [...]int{5, 6, 7, 8, 8} fmt.Println("before passing to function ", num) changeLocal(&num) //num is passed by value fmt.Println("after passing to function ", num) }
在上述程序的 13 行中, 数组 num 实际上是通过值传递给函数 changeLocal,数组不会因为函数调用而改变。这个程序将输出,
1 2 3
before passing to function [5 6 7 8 8] inside function [55 6 7 8 8] after passing to function [5 6 7 8 8]
数组的长度
通过将数组作为参数传递给 len 函数,可以得到数组的长度。
1 2 3 4 5 6 7 8
package main
import"fmt"
funcmain() { a := [...]float64{67.7, 89.8, 21, 78} fmt.Println("length of a is",len(a)) }
上面的程序输出为 length of a is 4。
使用 range 迭代数组
for 循环可用于遍历数组中的元素。
1 2 3 4 5 6 7 8 9 10
package main
import"fmt"
funcmain() { a := [...]float64{67.7, 89.8, 21, 78} for i := 0; i < len(a); i++ { // looping from 0 to the length of the array fmt.Printf("%d th element of a is %.2f\n", i, a[i]) } }
上面的程序使用 for 循环遍历数组中的元素,从索引 0 到 length of the array - 1。这个程序运行后打印出,
1 2 3 4
0 th element of a is 67.70 1 th element of a is 89.80 2 th element of a is 21.00 3 th element of a is 78.00
Go 提供了一种更好、更简洁的方法,通过使用 for 循环的 range 方法来遍历数组。range 返回索引和该索引处的值。让我们使用 range 重写上面的代码。我们还可以获取数组中所有元素的总和。
1 2 3 4 5 6 7 8 9 10 11 12 13
package main
import"fmt"
funcmain() { a := [...]float64{67.7, 89.8, 21, 78} sum := float64(0) for i, v := range a {//range returns both the index and value fmt.Printf("%d the element of a is %.2f\n", i, v) sum += v } fmt.Println("\nsum of all elements of a",sum) }
上述程序的第 8 行 for i, v := range a 利用的是 for 循环 range 方式。 它将返回索引和该索引处的值。 我们打印这些值,并计算数组 a 中所有元素的总和。 程序的 输出是,
1 2 3 4 5 6
0 the element of a is 67.70 1 the element of a is 89.80 2 the element of a is 21.00 3 the element of a is 78.00
funcmain() { numa := [3]int{78, 79 ,80} nums1 := numa[:] // creates a slice which contains all elements of the array nums2 := numa[:] fmt.Println("array before change 1", numa) nums1[0] = 100 fmt.Println("array after modification to slice nums1", numa) nums2[1] = 101 fmt.Println("array after modification to slice nums2", numa) }
funcmain() { var names []string//zero value of a slice is nil if names == nil { fmt.Println("slice is nil going to append") names = append(names, "John", "Sebastian", "Vinay") fmt.Println("names contents:",names) } }
在上面的程序 names 是 nil,我们已经添加 3 个字符串给 names。该程序的输出是
1 2
slice is nil going to append names contents: [John Sebastian Vinay]
funcsubtactOne(numbers []int) { for i := range numbers { numbers[i] -= 2 } } funcmain() { nos := []int{8, 7, 6} fmt.Println("slice before function call", nos) subtactOne(nos) // function modifies the slice fmt.Println("slice after function call", nos) // modifications are visible outside }